package common.jisc.manager;

import common.jisc.exception.UnknownCommandException;

import java.io.Console;
import java.util.Scanner;

/**
 * User: Denis Fahritdinov
 * Date: 10/14/12
 * Time: 5:35 PM
 */
public class ConsoleCommandManager extends DefaultCommandManager {

    private HelpHandler helpHandler;
    private boolean extendedThrowUnknownCommandException;


    public ConsoleCommandManager(HelpHandler helpHandler) {
        this.helpHandler = helpHandler;
        this.throwUnknownCommandException = true;
        this.extendedThrowUnknownCommandException = false;
    }

    public void setHelpHandler(HelpHandler helpHandler) {
        this.helpHandler = helpHandler;
    }

    public void removeHelpHandler() {
        helpHandler = null;
    }

    /**
     * @return throw exception if command was not handled
     */
    public boolean isThrowUnknownCommandException() {
        return extendedThrowUnknownCommandException;
    }

    /**
     * @param throwUnknownCommandException throw exception if command was not handled
     */
    public void setThrowUnknownCommandException(boolean throwUnknownCommandException) {
        this.extendedThrowUnknownCommandException = throwUnknownCommandException;
    }

    /**
     * Handle user command
     *
     * @param command
     */
    @Override
    public void handle(String command) {
        try {
            super.handle(command);
        } catch (UnknownCommandException e) {
            if (helpHandler != null) {
                helpHandler.help(help());
            }
            if (extendedThrowUnknownCommandException) {
                throw e;
            }
        }
    }

    /**
     * Start handle console commands
     */
    public void start() {
        Console console = System.console();
        Scanner scanner = new Scanner(console.reader());
        while (scanner.hasNextLine()) {
            String command = scanner.nextLine();
            handle(command);
        }
        scanner.close();
    }

    /**
     * Start handle console commands in new thread
     */
    public synchronized void startInNewThread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                start();
            }
        }).start();
    }

    public static interface HelpHandler {
        void help(String helpMessage);
    }
}
